Release 10.1A: OpenEdge Development:
Progress Dynamics Advanced Development
Disabling actions based on a data value
For example, suppose that you want users of the
oemaintwinwindow you built to be able to edit or delete onlyCustomersandOrdersforCustomersin the USA. To do this, you must disable the buttons that allow those operations, depending on the value of the currently selectedCustomer, and enable or disable the fields in the viewers on the different folder pages accordingly.Using the TableIOType property
The first thing you must do is to change the basic display mode of the toolbar to leave viewers disabled until someone specifically wants to do an update. That way, the viewers are initially disabled, and the user must have access to the Modify button to make changes.
In earlier versions of the ADM and its SmartPanels, this was done with the
PanelTypeproperty, which you could set to one of two states:
Save— Puts the buttons and theirTableIO-Targets into a state where everything is enabled and the user just makes changes and selects the Save button to record them.Update— DisablesTableIO-Targets and places the buttons into a state where the user must select the Update button to enable the viewers and begin to make changes, and then select Save when done.The toolbar equivalent of this property is
TableIOType, and it has the same two possible values:SaveandUpdate. The default setting isSave, so things start out enabled. You must change the setting toUpdatefor this example to work. Change the value in the Container Builder, by bringing up the toolbar’s dynamic property sheet, as shown in Figure 3–9, and changing the property value there.Figure 3–9: Dynamic Properties window
![]()
There is another way to make run-time changes to the object in a custom super procedure that executes custom code when the window is initialized. You can define a custom super procedure for the toolbar itself, but because this must be done as part of the overall window initialization, this example shows the code in a custom super procedure for the container window. Where you put your code is a matter of overall organization and preference; there is always more than one solution to a programming problem.
Defining a custom super procedure for the window
Define a New Structured Procedure in the AppBuilder and create an
initializeObjectinternal procedure for it. Because this code is executed on behalf of the window, it first must get the handle of theToolbarobject. To do this, add aContainerToolbarlink from the toolbar to the window (THIS-OBJECT), which might be useful for other purposes as well, as is described in a later section of this chapter. Alternatively, the code could simply check among the window’sContainer-Targetsfor the handle of an object with theObjectNameofFolderPageTop. Again, there is almost always more than one way to solve a problem.Given the toolbar handle, you then must set the
TableIOTypeproperty toUpdate. This code sample uses the{get}and{set}include files to do the job. You could also use theDYNAMIC-FUNCTIONsyntax and the equivalentgetandsetfunctions for the same effect. This is also mostly a matter of personal preference and coding style. This all must happen before theRUN SUPERstatement so that the property is set before all the objects are initialized, as shown in the following code:
Registering the custom super procedure
As always, remember to register your super procedure in the Repository by selecting that option in the AppBuilder’s File menu. Save it as a Procedure in the appropriate product module. We have called the procedure oemaintwinsuper.p.
Once you have done this, attach it as the custom super procedure for the container window. You can do this in the Container Builder, as shown in Figure 3–10.
Figure 3–10: Container Builder for oemaintwin
![]()
Note that you can set the custom super procedure for objects that are edited in the AppBuilder, such as browsers and viewers, in the AppBuilder’s property sheets for those objects.
As mentioned elsewhere, you do not specify the relative pathname where the procedure is actually stored because you are just providing its
LogicalObjectNameas stored in the Repository. This name includes the .p filename extension but not the pathname. The pathname is attached automatically at run time by looking up the product module record in the Repository.Defining a custom super procedure for a viewer
Now that you have set the
TableIOTypeproperty, you must create code to selectively enable and disable both the toolbar buttons and the viewer fields depending on the value of the Customer Country field. Put this code into a custom super procedure for thecustcommentsvviewer that we have named customersuper.p. See the "Defining a custom super procedure for the window" section for more information on how to create this procedure.Using the modifyDisabledActions procedure In the toolbar
To control the toolbar buttons and associated menu items, change the
DisabledActionsorHiddenActionsattributes. In this example, you should disable the buttons and menu items rather than hide them so that they do not appear and disappear as the user changes records, which would not be an appropriate user interface. In other situations you can remove the button or menu item from the toolbar altogether by adding it to theHiddenActionsproperty.There is a special support procedure to help you add and remove entries from the
DisabledActionsproperty, whose value is a comma-separated list of actions. Note that at present there is no equivalent procedure forHiddenActions; you will have to parse the list yourself or create your ownmodifyHiddenActionsprocedure based onmodifyDisabledActions.First you must identify the names of the actions that you are going to disable. To identify these names, open the toolbar in the Toolbar and Menu Designer. Expand the SmartToolbars node and locate the toolbar you are using, which is
FolderPageTopin this case. Expand that node to see the bands it uses, and then expand theTableIoModband, which holds all the update-related actions. Here you can see the description of each action.Following the description is the actual action name in parentheses, which also appears as the Item Reference in the maintenance frame to the right, as shown in Figure 3–11. This is the name to use in setting
DisabledActions.Figure 3–11: Toolbar and Menu designer
![]()
To disable the Delete button in the
FolderPageToptoolbar, and also the two buttons that allow you to alternate the state of the displayed record fromViewmode toUpdatemode, you must add Delete, FolderView, and FolderUpdate to the list.Since you need to do this each time a
Customeris selected, the appropriate place for the code is in a local version of thedataAvailableevent procedure. This is published by the SDO each time the record position changes and the viewer subscribes to the event so that it can display the new values. Unlike most event procedures, which have no parameters, this one has a singleINPUTparameter that you must define and pass on to the super procedure. See Chapter 5, "Using ADM2 Properties and Methods in Progress Dynamics," for more information on this and many other useful properties and entry points in the code that you might want to use.Important note about parameters on overrides and publish
Remember to double-check for parameters in any procedure that you are going to override and in any event that you publish. If you get the parameter list wrong for a local version of a procedure that you
RUN, you will get an error at run time to remind you of your mistake. But if you get the calling sequence wrong for aPUBLISHstatement, the event simply will not occur because there will not be any matching subscriber with the same parameter list.Unfortunately, when you create a custom super procedure and add code to it in the AppBuilder, the Section Editor is not aware of what object it will be associated with, so it cannot supply you with a list of all the valid procedures and functions you can override, along with their parameters, as it does when you add procedures to a static SmartObject. Therefore, make sure you get this right. Also, do not forget to include the
RUNSUPERstatement in the right place in your custom code. If you leave it out, the standard code for the event will not execute at all, and the results will likely be very strange.Getting values from different linked objects
Your custom code must first get the handle of the toolbar. Because there is no link from the toolbar to the
Commentsviewer (the viewer is not updateable, so it has noTableIOlink), you must get the handle of theCustomerSDO, which is the viewer’sData-Source, and then get the SDO’sNavigation-Source, which is the toolbar.You also need to retrieve the value of the Country field for the selected record. You can use the
columnValuefunction in the SDO to do this.And finally, the code must get a list of all the
TableIO-Targets of the toolbar (which are the three updateable viewers on Pages 2, 3, and 4). This is theTableIOTargetproperty. Though the name is singular (target not targets), the data type isCHARACTER, because there might be a list of handles of multiple targets, stored as a comma-separated list of handles in string form, as shown in the following:
Next, the code checks the value of the
Countryfield and runs modifyDisabledActionsto either add or remove the actions. Remember that the goal is to allow users to edit and delete only records related to customers in the USA. ThemodifyDisabledActionsprocedure takes two arguments:If the country is USA, the user is allowed to do updates and deletes, so the actions are removed from the disabled list, as shown:
Using enableFields and disableFields
Then the code goes through the list of
TableIO-Targets, converts each back to a handle, and runs the enableFields procedure in it. In order to avoid doing this unnecessarily, it first checks the value of the viewer’sFieldsEnabledproperty to see whether the fields are already in the right state, as shown:
Correspondingly, if the country is not equal to USA, then the actions are added to the disabled list and the code must run the disableFields procedure in the viewer. This is another case where you have to be careful to get the calling sequence right. Unlike
enableFields, thedisableFieldsprocedure takes anINPUTparameter, which can beAllorCreateto indicate whether all fields are to be disabled, or just those associated with creating a new record, as shown:
This is the end of the code for the viewer’s localization of
dataAvailable. Be sure to register the super procedure in the Repository and associate it with the viewer. You can set the custom super procedure for the viewer in the Repository Maintenance tool, or more conveniently in the AppBuilder, by opening the viewer and going into its property sheet, as shown in Figure 3–12.Figure 3–12: Property sheet for frMain
![]()
Testing the window with DisabledActions
Now, when you run the application window and select a customer not in the USA, all the viewers are disabled. The
Delete,View, andModifyactions in the toolbar are also disabled, as shown in Figure 3–13.Figure 3–13: Test of window wIth DisabledActions
![]()
Using the toolbar’s reset procedures
The toolbar uses a set of event procedures to reset the action state for various types of actions. These procedures are executed when it seems correct to check for a state change. As a result, you do not normally need to run them yourself. For instance, they are run on a page change, which is why the action state is corrected when you switch pages.
The event procedures that the toolbar supports are
resetTableIo,resetCommit, andresetNavigation. These are published by objects like the viewer, and generally you do not need to invoke them explicitly. If you find that the toolbar state is not being reset properly at some particular place in your application, such as this viewer, you can simply publish the event from the viewer and the toolbar will receive it.Remember to publish it
FROM TARGET-PROCEDUREso that the event is associated with the viewer itself and not its super procedure. This is what the first block of code looks like with an example of publishingresetTableIoto make sure that the update buttons are reset properly:
You can also publish the general-purpose reset procedure
resetTargetActionsto reset actions related to other link types, including custom links of your own. The procedure takes the name of the link as anINPUTparameter.
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |